package com.pf.common.utils;

import org.apache.commons.collections.CollectionUtils;
import org.assertj.core.util.Lists;

import java.lang.annotation.Annotation;
import java.lang.reflect.Field;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * 自定义Bean工具类
 *
 * @author PanFei
 * @version 1.0.0
 * @createTime 2023/4/25 21:01
 */
public class CustomBeanUtils {

    /**
     * 向上级联获取含某注解的字段集合
     *
     * @param clazz               目标实体类型
     * @param annotationClassList 目标注解集合
     * @return 含有目标注解的字段集合
     */
    public static Map<Class<? extends Annotation>, List<Field>> getRecursiveFieldsByUpward(Class<?> clazz, List<Class<? extends Annotation>> annotationClassList) {
        Map<Class<? extends Annotation>, List<Field>> annotationFieldMap = new HashMap<>();
        getRecursiveFieldsByUpward(clazz, annotationClassList, annotationFieldMap);
        return annotationFieldMap;
    }

    /**
     * 向上级联获取含某注解的字段集合
     *
     * @param clazz               目标实体类型
     * @param annotationClassList 目标注解集合
     * @param annotationFieldMap  含有目标注解的字段集合
     */
    private static void getRecursiveFieldsByUpward(Class<?> clazz, List<Class<? extends Annotation>> annotationClassList, Map<Class<? extends Annotation>, List<Field>> annotationFieldMap) {
        Field[] fields = clazz.getDeclaredFields();
        for (Field field : fields) {
            for (Class annotationClass : annotationClassList) {
                if (field.isAnnotationPresent(annotationClass)) {
                    List<Field> fieldList = annotationFieldMap.get(annotationClass);
                    if (CollectionUtils.isEmpty(fieldList)) {
                        annotationFieldMap.put(annotationClass, Lists.newArrayList(field));
                    } else {
                        fieldList.add(field);
                    }
                }
            }
        }

        Class<?> superclass = clazz.getSuperclass();
        if (superclass != null && !superclass.equals(Object.class)) {
            getRecursiveFieldsByUpward(superclass, annotationClassList, annotationFieldMap);
        }
    }
}
